﻿using System;
using System.Collections.Generic;
using System.Text;
using OpenGameEngine.GameObjects;
using OpenGameEngine.Input;
using swf = System.Windows.Forms;
using OpenGameEngine.Base;
using OpenGameEngine.Scenes;

namespace OpenGameEngine.Gui
{
    public abstract class Control : GameObject
    {
        private Boolean _mouseEntered;
        private Boolean _mouseDown;
        private Boolean _focused;

        public String Text { get; set; }
        public SizeF Size { get; set; }
        public Boolean Focussed { get { return _focused; } }
        public RectangleF ActualBounds
        {
            get
            {
                RectangleF myBounds = new RectangleF(Position, Size);
                myBounds.Inflate(2, 2);
                return myBounds;
            }
        }

        private Color _bgColor = Color.Wheat;
        private Color _fgColor = Color.Black;

        public Color BackColor
        {
            get { return _bgColor; }
            set
            {
                _bgColor = value;
                _solidColorBrush = new SolidColorBrush(value);
            }
        }

        public Color ForeColor
        {
            get { return _fgColor; }
            set { _fgColor = value; }
        }


        private SolidColorBrush _solidColorBrush;
        private SolidColorBrush _borderBrush = new SolidColorBrush(Color.Black);

        public Control(Vector2 location, SizeF size)
            : base()
        {
            this.AcceptsKeyboardInput = true;
            this.AcceptsMouseInput = true;
            this.Enabled = true;
            this.Visible = true;
            this.Position = location;
            this.Size = size;
            _solidColorBrush = new SolidColorBrush(this.BackColor);
        }

        private void CheckForInput(Base.GameCoreEventArgs e)
        {
            if (AcceptsMouseInput)
            {
                MouseStateInfo prevMouse = e.Core.PreviousMouseStateInfo;
                MouseStateInfo mouse = e.Core.CurrentMouseStateInfo;
                Vector2 v = mouse.MouseLocation;
                RectangleF d = this.ActualBounds;

                if (v.X > d.X && v.Y > d.Y && v.X < (d.X + d.Width) && v.Y < (d.Y + d.Height))
                {
                    if (!_mouseEntered)
                    {
                        MouseEnter(e);
                        _mouseEntered = true;
                    }

                    foreach (swf.MouseButtons b in Globals.MouseButtons)
                    {
                        bool blnCurrMs = mouse[b];
                        bool blnPrevMs = prevMouse[b];

                        if (blnCurrMs)
                        {
                            MouseDown(e, b);
                        }
                        else if (blnPrevMs && !blnCurrMs)
                        {
                            MouseUp(e, b);
                            MouseClick(e, b);
                        }
                    }
                }
                else
                {
                    if (_mouseEntered)
                    {
                        MouseLeave(e);
                        _mouseEntered = false;
                    }
                }
            }
        }

        public void Focus(GameCoreEventArgs e)
        {
            GameScene gs = e.Core.CurrentScene;
            Control[] ctrls = new Control[gs.Controls.Count];
            gs.Controls.CopyTo(ctrls, 0);

            foreach (Control c in ctrls)
                c._focused = false;

            this._focused = true;
        }

        public override void Update(Base.GameCoreEventArgs e)
        {
            if (_focused)
                base.Update(e);

            CheckForInput(e);
        }

        public override void Draw(DrawEventArgs e)
        {
            base.Draw(e);

            e.FillRectangle(this.ActualBounds, _solidColorBrush);
            e.DrawRectangle(this.ActualBounds, _borderBrush);
        }

        public override void MouseClick(Base.GameCoreEventArgs e, swf.MouseButtons button)
        {
            base.MouseClick(e, button);

            Focus(e);
        }

        public override string ToString()
        {
            return this.Text;
        }
    }
}
